
package com.ps.helpdesk.persistence;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import javax.persistence.RollbackException;

import oracle.toplink.essentials.exceptions.DatabaseException;

public class ManagerEntity<T> implements DAO<T> {

	private final EntityManager m = ManagerConnection.getInstance().getManager();
	
	private String mensagem;

	public ManagerEntity() {
	}
	
	public String getMensagem() {	
		return mensagem;
	}
	
	private void setMensagem( String mensagem ) {	
		this.mensagem = mensagem;
	}

	public T find( Class<T> classe, Object key ) {

		T entity = null;
		try {
			entity = (T) m.find( classe, key );
			if ( entity != null ) {
				m.refresh( entity );
				return entity;
			}
		} catch ( EntityNotFoundException e ) {
			e.printStackTrace();
			remove( entity );
		} catch ( Exception e ) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * Cria uma lista usando o createNamedQuery.
	 * 
	 * @param queryname
	 *            Nome da query.
	 * @return lista de entidades.
	 */
	public List<T> list( String queryname ) {

		List<T> entitys = null;
		EntityTransaction tx = m.getTransaction();
		try {
			tx.begin();
			Query query = m.createNamedQuery( queryname );
			entitys = query.getResultList();
			tx.commit();
		} catch ( RuntimeException e ) {
			e.printStackTrace();
			tx.rollback();
		}

		return entitys;
	}

	public List<T> list( Query query ) {

		List<T> entitys = null;
		EntityTransaction tx = m.getTransaction();
		try {
			tx.begin();
			entitys = query.getResultList();
			tx.commit();
		} catch ( RuntimeException e ) {
			e.printStackTrace();
			tx.rollback();
		}

		return entitys;
	}

	public boolean persist( T entity ) {

		boolean actionReturn = false;
		EntityTransaction tx = m.getTransaction();
		try {
			tx.begin();
			m.persist( entity );
			tx.commit();
			actionReturn = true;
		} catch ( RollbackException e ) {
			setMensagem( "Erro ao persistir!" );
			e.printStackTrace();
			tx.rollback();
		} catch ( RuntimeException e ) {
			setMensagem( "Erro ao persistir!" );
			e.printStackTrace();
			tx.rollback();
		}
		return actionReturn;
	}

	public boolean remove( T entity ) {

		boolean actionReturn = false;
		EntityTransaction tx = m.getTransaction();
		try {
			tx.begin();
			T etmp = m.merge( entity );
			m.remove( etmp );
			tx.commit();
			actionReturn = true;
		} catch ( DatabaseException e ) {
			String msg = "Erro ao remover!";
			if ( e.getErrorCode() == 4002 ) {
				msg += "O registro possue vinculos!";
			}
			setMensagem( msg );
			e.printStackTrace();
			tx.rollback();
		} catch ( RuntimeException e ) {
			setMensagem( "Erro ao remover!" );
			e.printStackTrace();
			tx.rollback();
		}
		return actionReturn;
	}
}
